package main
/*
其本身并不是数组，它指向底层的数组
作为变长数组的替代方案，可以关联底层数组的局部或全部
为引用类型
可以直接创建或从底层数组获取生成
使用len()获取元素个数，cap()获取容量
一般使用make()创建
如果多个slice指向相同底层数组，其中一个的值改变会影响全部,除非一个Slice append 元素超过cap,引起slice 扩容，不再指向原来的地址，就会丢弃未被slice的数组部分

make([]T, len, cap)
其中cap可以省略，则和len的值相同
len表示存数的元素个数，cap表示容量
 */
import "fmt"

func main()  {
	a:=[10]int{1,2,3,4,5,6,7,8,9}
	fmt.Println("a: ",a)

	s1:=a[5:10]   //不包括 10
	fmt.Println("s1: ",s1)
	s2:=a[5:len(a)]
	fmt.Println("s2: ",s2)
	s3:=a[5:cap(a)]
	fmt.Println("s3: ",s3)
	s4:=a[5:]		//索引5之后的所有元素
	fmt.Println("s4: ",s4)
	s5:=a[:5] //a[0:5]		//索引5之前的所有元素
	fmt.Println("s5: ",s5)


	slice:=make([]int,3,10)	//类型，目前包含元素，初始容量(递增策略：*2)
	fmt.Println("slice: ",slice,"now: ",len(slice),"cap: ",cap(slice))
	slice1:=make([]int,3)

	fmt.Println("slice1: ",slice1,"now: ",len(slice1),"cap: ",cap(slice1))
/*
	Reslice时索引以被slice的切片为准
	索引不可以超过被slice的切片的容量cap()值
	索引越界不会导致底层数组的重新分配而是引发错误
*/
	b:=[]byte{'a','b','c','d','e','f','g','h','i','g'}
	slice2:=b[2:5]
	fmt.Println("slice2: ",string(slice2),"now: ",len(slice2),"cap: ",cap(slice2))
	slice3:=slice2[2:5]		//再取切面则相当于索引以实例slice2开始
	fmt.Println("slice3: ",string(slice3),"now: ",len(slice3),"cap: ",cap(slice3))

/*
Append
可以在slice尾部追加元素
可以将一个slice追加在另一个slice尾部
如果最终长度未超过追加到slice的容量则返回原始slice
如果超过追加到的slice的容量则将重新分配数组并拷贝原始数据

 */
	sli:=make([]int,3)
	fmt.Printf("%v %p\n",sli,sli)
	sli[2]=10
	sli=append(sli,1,2,3,4,5,6)
	fmt.Printf("%v %p\n",sli,sli)


/*
Copy
 */
	c:=[]byte{'1','2','3','4','5','6','7','8','9','0'}
	fmt.Println(c)
	fmt.Println(b,copy(c,b),c)
	fmt.Printf("%p %p\n",b,c)

	//i索引，k元素值,都是值引用
	for i,k:=range c {
		fmt.Println(i,"/",k)
	}
}
